import crcmod


def 十进制转十六进制(val, nbits):
    # 这个函数和python自带的hex函数不同, 因为在指定了
    # 16进制数的宽度以后, 它可以消除待转换数的符号.
    return hex((val + (1 << nbits)) % (1 << nbits))


def 十进制数转字节流(数值, 宽度):
    # 这里的宽度的单位是字节, 且数值必须是整数
    assert(isinstance(数值, int) and isinstance(宽度, int))
    临变 = 十进制转十六进制(数值, 宽度*8)
    临变 = 临变[2:]
    结果 = bytearray.fromhex(临变)
    return 结果


def 累积序列(序列):
    assert(isinstance(序列, list))
    for i in range(1, len(序列)):
        序列[i] += 序列[i-1]
    return 序列


hash1 = crcmod.mkCrcFun(0x104c11db7, initCrc=0, xorOut=0xFFFFFFFF)
hash2 = crcmod.mkCrcFun(0x11edc6f41, initCrc=0, xorOut=0xFFFFFFFF)
hash3 = crcmod.mkCrcFun(0x1a833982b, initCrc=0, xorOut=0xFFFFFFFF)
hash4 = crcmod.mkCrcFun(0x1814141ab, initCrc=0, xorOut=0xFFFFFFFF)
hash5 = crcmod.mkCrcFun(0x15a0849e7, initCrc=0, xorOut=0xFFFFFFFF)
hash6 = crcmod.mkCrcFun(0x128ba08bb, initCrc=0, xorOut=0xFFFFFFFF)
hash7 = crcmod.mkCrcFun(0x13b328ffb, initCrc=0, xorOut=0xFFFFFFFF)
hash8 = crcmod.mkCrcFun(0x10e92c2cd, initCrc=0, xorOut=0xFFFFFFFF)
hash9 = crcmod.mkCrcFun(0x11c46e3df, initCrc=0, xorOut=0xFFFFFFFF)
hash10 = crcmod.mkCrcFun(0x118e8dda9, initCrc=0, xorOut=0xFFFFFFFF)


def 哈希(序号, 字符串):
    assert(序号 >= 0 and 序号 < 10 and isinstance(字符串, str))
    函数 = [hash1, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9, hash10]
    return 函数[序号](字符串.encode("utf-8"))


# ---------- 求相关性 ---------- #
# 我们首先对序列1进行去重, 然后计算序列2中的元素中, 已经在序列1中
# 出现过的比例.
# -------------------- #
def 求相关度(序列1, 序列2):
    assert(isinstance(序列1, list) and isinstance(序列2, list))
    print("len1:%d, len2:%d" % (len(序列1), len(序列2)))
    池子 = set()
    for 子项 in 序列1:
        池子.add(子项)
    计数值 = 0
    for 子项 in 序列2:
        if 子项 in 池子:
            计数值 += 1
    return float(计数值)/len(序列2)


# ---------- 求交集 ---------- #
def 求交集(序列1, 序列2):
    assert(isinstance(序列1, list) and isinstance(序列2, list))
    集合1 = set(序列1)
    集合2 = set(序列2)
    return 集合1.intersection(集合2)
# -------------------- #


def 求横坐标(pt1, pt2, y):
    x1, y1 = pt1
    x2, y2 = pt2
    k = float(y2 - y1)/float(x2 - x1)
    c = y1 - k*x1
    x = (y - c)/k
    return x


class 线性拟合:
    def __init__(self, 目标值):
        self.目标值 = 目标值
        self.上限 = (-1, -1)
        self.下限 = (-1, -1)

    def 更新(self, 二元组):
        x, y = 二元组
        if y >= self.目标值:
            if (-1, -1) == self.上限 or y < self.上限[1]:
                self.上限 = (x, y)
        if y <= self.目标值:
            if (-1, -1) == self.下限 or y > self.下限[1]:
                self.下限 = (x, y)

    def 计算拟合结果(self):
        assert((-1, -1) != self.上限 and (-1, -1) != self.下限)
        return 求横坐标(self.目标值, self.下限, self.上限)
